/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.kramerius.articles.importFromLn.articlesData.jiranova;

import cz.mzk.kramerius.articles.importFromLn.PropertyNames;
import cz.mzk.kramerius.articles.importFromLn.articlesData.ArticleComponents;
import cz.mzk.kramerius.articles.importFromLn.articlesData.errors.ArticleError;
import cz.mzk.kramerius.articles.importFromLn.articlesData.errors.EmptyFieldError;
import cz.mzk.kramerius.articles.importFromLn.articlesData.errors.UnknownGenreError;
import cz.mzk.kramerius.articles.importFromLn.domain.Article;
import cz.mzk.kramerius.articles.importFromLn.domain.ArticleComponent;
import cz.mzk.kramerius.articles.importFromLn.domain.Author;
import cz.mzk.kramerius.articles.importFromLn.domain.Genre;
import cz.mzk.kramerius.articles.importFromLn.domain.Language;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Martin Řehánek (rehan@mzk.cz)
 */
public class ArticleBuilder {

    private static final Logger logger = Logger.getLogger(ArticleBuilder.class.getName());
    private static final String GENRE = "žánr";
    private static final String LANGUAGE = "jazyk";
    private static final String AUTHOR = "autor";
    private static final String TITLE = "název";
    private final int articleId;
    private final Article article = new Article();
    private ErroneousArticleImpl erroneousArticle;
    //private final List<String> errorMessages = new ArrayList<String>();
    private final List<ArticleError> errors = new ArrayList<ArticleError>();
    private List<ArticleComponent> articleComponents;
    private final Requirements requirements;

    public ArticleBuilder(int articleId, Requirements requirements) {
        this.articleId = articleId;
        this.requirements = requirements;
    }

    /**
     * @return the article
     */
    public Article getArticle() {
        article.setArticleComponents(articleComponents);
        return article;
    }

    /**
     * @return the erroneousArticle
     */
    ErroneousArticleImpl getErroneousArticle() {
        return erroneousArticle;
    }

    /**
     * @param erroneousArticle the erroneousArticle to set
     */
    void setErroneousArticle(ErroneousArticleImpl erroneousArticle) {
        this.erroneousArticle = erroneousArticle;
    }

    /**
     * @return the errorMessages
     */
    public List<String> getErrorMessages() {
        List<String> errorMessages = new ArrayList<String>();
        for (ArticleError error : errors) {
            errorMessages.add(error.getErrorMessage());
        }
        return errorMessages;
    }

    List<ArticleError> getErrors() {
        return errors;
    }

    public void setGenre(Genre genre) {
        article.setGenre(genre);
    }

    void processGenre(String genreStr) {
        Genre genre = String2Genre(genreStr);
        if (genre != Genre.UNKNOWN) {
            article.setGenre(genre);
        } else {
            errors.add(new UnknownGenreError(genreStr));
        }
    }

    private Genre String2Genre(String value) {
        try {
            int intValue = Integer.valueOf(value);
            return Genre.valueOf(intValue);
        } catch (NumberFormatException ex) {
            logger.log(Level.SEVERE, "incorrect genre ''{0}'', articleId: {1}", new Object[]{value, articleId});
            return Genre.UNKNOWN;
        }
    }

    public void processLanguage(String languageStr) {
        Language language = Language.parseLanguage(languageStr);
        if (language == Language.unknown && requirements.isRequired(PropertyNames.REQUIRE_LANGUAGE_NOT_EMPTY)) {
            errors.add(new EmptyFieldError((LANGUAGE)));
        }
        article.setLanguage(language);
    }

    public void processAuthor(String authorStr) {
        if (!nullOrWhitespaces(authorStr)) {
            article.setAuthor(new Author(authorStr, articleId));
        } else {
            article.setAuthor(new Author(null, articleId));
            if (requirements.isRequired(PropertyNames.REQUIRE_AUTHOR_NOT_EMPTY)) {
                errors.add(new EmptyFieldError((AUTHOR)));
            }
        }
    }

    public void processTitle(String titleStr) {
        if (!nullOrWhitespaces(titleStr)) {
            article.setTitle(titleStr);
        } else {
            article.setTitle(null);
            if (requirements.isRequired(PropertyNames.REQUIRE_TITLE_NOT_EMPTY)) {
                errors.add(new EmptyFieldError((TITLE)));
            }
        }
    }

    public void procesSubtitle(String subtitleStr) {
        if (!nullOrWhitespaces(subtitleStr)) {
            article.setSubTitle(subtitleStr);
        } else {
            article.setSubTitle(null);
        }
    }

    public void procesInfo(String infoStr) {
        if (!nullOrWhitespaces(infoStr)) {
            article.setInfo(infoStr);
        } else {
            article.setInfo(null);
        }
    }

    void processNote(String noteStr) {
        if (!nullOrWhitespaces(noteStr)) {
            article.setNote(noteStr);
        } else {
            article.setNote(null);
        }
    }

    private boolean nullOrWhitespaces(String string) {
        if (string == null) {
            return true;
        }
        for (int i = 0; i < string.length(); i++) {
            char c = string.charAt(i);
            if (!Character.isWhitespace(c)) {
                return false;
            }
        }
        return true;
    }

    public boolean hasErrors() {
        return !errors.isEmpty();
    }

    public void addArticleComponents(ArticleComponents articleComponents) {
        if (this.articleComponents == null) {
            this.articleComponents = articleComponents.getComponents();
        } else {
            this.articleComponents.addAll(articleComponents.getComponents());
        }
        if (articleComponents.hasError()) {
            errors.add(articleComponents.getError());
        }
    }
}
